Passed
Branch master (32b4c5)
by Askupa
01:33
created

Mivhak.calculateHeight   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
c 0
b 0
f 0
nc 12
nop 1
dl 0
loc 16
rs 8.2222
1
/**
2
 * The constructor.
3
 * See Mivhal.defaults for available options.
4
 * 
5
 * @param {DOMElement} selection
6
 * @param {Object} options
7
 */
8
function Mivhak( selection, options )
9
{   
10
    // Bail if there are no resources
11
    if(!selection.getElementsByTagName('PRE').length) return;
12
    
13
    this.$selection = $( selection );
14
    this.setOptions( options );
15
    this.init();
16
}
17
18
/**
19
 * Check if a given string represents a supported method
20
 * @param {string} method
21
 */
22
Mivhak.methodExists = function( method )
23
{
24
    return typeof method === 'string' && Mivhak.methods[method];
25
};
26
27
/**
28
 * Initiate the code viewer.
29
 */
30
Mivhak.prototype.init = function() 
31
{
32
    this.initState();
33
    this.parseResources();
34
    this.createUI();
35
    this.applyOptions();
36
    this.callMethod('showTab',0); // Show first tab initially
37
};
38
39
/**
40
 * Apply the options that were set by the user. This function is called when
41
 * Mivhak is initiated, and every time the options are updated.
42
 */
43
Mivhak.prototype.applyOptions = function() 
44
{
45
    this.callMethod('setHeight', this.options.height);
46
    this.callMethod('setAccentColor', this.options.accentColor);
47
    if(this.options.collapsed) this.callMethod('collapse');
48
    if(!this.options.topbar) this.$selection.addClass('mivhak-no-topbar');
49
    else this.$selection.removeClass('mivhak-no-topbar');
50
    
51
    this.createCaption();
52
    this.createLivePreview();
53
};
54
55
/**
56
 * Initiate this instance's state.
57
 */
58
Mivhak.prototype.initState = function() 
59
{
60
    this.state = {
61
        lineWrap:   true,
62
        collapsed:  false,
63
        height:     0,
64
        activeTab:  null,   // Updated by tabs.showTab
65
        resources:  []    // Generated by parseResources()
66
    };
67
};
68
69
/**
70
 * Set or update this instance's options.
71
 * @param {object} options
72
 */
73
Mivhak.prototype.setOptions = function( options ) 
74
{
75
    // If options were already set, update them
76
    if( typeof this.options !== 'undefined' )
77
        this.options = $.extend(true, {}, this.options, options, readAttributes(this.$selection[0]));
78
    
79
    // Otherwise, merge them with the defaults
80
    else this.options = $.extend(true, {}, Mivhak.defaults, options, readAttributes(this.$selection[0]));
81
};
82
83
/**
84
 * Call one of Mivhak's methods. See Mivhak.methods for available methods.
85
 * To apply additional arguments, simply pass the arguments after the methodName
86
 * i.e. callMethod('methodName', arg1, arg2).
87
 * This method is also called internally when making a method call through jQuery
88
 * i.e. $('#el').mivhak('methodName', arg1, arg2);
89
 * 
90
 * @param {string} methodName
91
 */
92
Mivhak.prototype.callMethod = function( methodName )
93
{
94
    if(Mivhak.methodExists(methodName))
95
    {
96
        // Call the method with the original arguments, removing the method's name from the list
97
        var args = [];
98
        Array.prototype.push.apply( args, arguments );
99
        args.shift();
100
        Mivhak.methods[methodName].apply(this, args);
101
    }
102
};
103
104
/**
105
 * Create the user interface.
106
 */
107
Mivhak.prototype.createUI = function() 
108
{
109
    this.tabs = Mivhak.render('tabs',{mivhakInstance: this});
110
    this.topbar = Mivhak.render('top-bar',{mivhakInstance: this});
111
    this.notifier = Mivhak.render('notifier');
112
    
113
    this.$selection.prepend(this.tabs.$el);
114
    this.$selection.prepend(this.topbar.$el);
115
    this.tabs.$el.prepend(this.notifier.$el);
116
};
117
118
/**
119
 * Calculate the height in pixels.
120
 * 
121
 * auto: Automatically calculate the height based on the number of lines.
122
 * min: Calculate the height based on the height of the tab with the maximum number of lines
123
 * max: Calculate the height based on the height of the tab with the minimum number of lines
124
 * average: Calculate the height based on the average height of all tabs
125
 * 
126
 * @param {string|number} h One of (auto|min|max|average) or a custom number
127
 * @returns {Number}
128
 */
129
Mivhak.prototype.calculateHeight = function(h)
130
{
131
    var heights = [],
132
        padding = this.options.padding*2,
133
        i = this.tabs.tabs.length;
134
135
    while(i--)
136
        heights.unshift(getEditorHeight($(this.tabs.tabs[i].resource.pre))+padding);
137
138
    if('average' === h) return average(heights);
139
    if('min' === h) return min(heights);
140
    if('max' === h) return max(heights);
141
    if('auto' === h) return getEditorHeight($(this.activeTab.resource.pre))+padding;
142
    if(!isNaN(h)) return parseInt(h);
143
    return heights[0];
144
};
145
146
/**
147
 * Loop through each PRE element inside this.$selection and store it's options
148
 * in this.resources, merging it with the default option values.
149
 */
150
Mivhak.prototype.parseResources = function()
151
{
152
    var $this = this;
153
    
154
    this.resources = new Resources();
155
    this.$selection.find('pre').each(function(){
156
        $this.resources.add(this);
157
    });
158
};
159
160
Mivhak.prototype.createCaption = function()
161
{
162
    if(this.options.caption)
163
    {
164
        if(!this.caption)
165
        {
166
            this.caption = Mivhak.render('caption',{text: this.options.caption});
167
            this.$selection.append(this.caption.$el);
168
        }
169
        else this.caption.setText(this.options.caption);
170
    }
171
    else this.$selection.addClass('mivhak-no-caption');
172
};
173
174
/**
175
 * Create the live preview iframe window
176
 */
177
Mivhak.prototype.createLivePreview = function()
178
{
179
    if(this.options.runnable && typeof this.preview === 'undefined')
180
    {
181
        this.preview = Mivhak.render('live-preview',{resources: this.resources});
182
        this.tabs.$el.append(this.preview.$el);
183
    }
184
};
185
186
/**
187
 * Remove all generated elements, data and events.
188
 * 
189
 * TODO: keep initial HTML
190
 */
191
Mivhak.prototype.destroy = function() 
192
{
193
    this.$selection.empty();
194
};
195
196
/* test-code */
197
testapi.mivhak = Mivhak;
198
/* end-test-code */